import {
  Card,
  Breadcrumb,
  Form,
  Button,
  Radio,
  Input,
  Upload,
  Space,
  message,
} from 'antd'
import { PlusOutlined } from '@ant-design/icons'
import { Link, useHistory, useParams } from 'react-router-dom'
import ReactQuill from 'react-quill'
import 'react-quill/dist/quill.snow.css'
import styles from './index.module.scss'
import { Channel } from '@/components/Channel'
import { useEffect, useRef, useState } from 'react'
import { useDispatch } from 'react-redux'
import { updateArticle, getArticleById } from '@/store/actions'

const Publish = () => {
  // 创建存储所有图片的 ref 对象
  const fileListRef = useRef([])
  const dispatch = useDispatch()
  const histroy = useHistory()

  // fileList 用来表示已上传的文件列表（图片数据列表）
  // 因为可以上传多张图片，所以，他的值是一个数组
  // 因为数组中的每一项都是一个对象，对象可以有很多属性，对我们使用来说 最主要的就是 图片 url 地址
  // 所以，此处，我们约定只需要提供url属性即可，因此  存储已上传的数据：
  // [{ url: '图片地址' }, { url: '图片地址' }]
  const [fileList, setFileList] = useState([])
  // 控制Upload组件图片上传数量
  const [maxCount, setMaxCount] = useState(1)

  // 创建 Form 实例
  const [form] = Form.useForm()
  // 获取路由参数
  const { id } = useParams()
  // 是否为编辑状态
  const isEdit = id !== undefined
  // 进入页面时，就发送请求，获取文章详情数据
  useEffect(() => {
    const loadData = async () => {
      // 判断是否为编辑状态，如果是，再发送请求：否则直接return
      if (!isEdit) return

      // 因为 dispatch 是异步action，所以 此处一定要通过 await 等待异步操作完成
      //      异步操作完成后 才能拿到action返回的文章详情数据
      const detail = await dispatch(getArticleById(id))
      // console.log(detail)
      const {
        title,
        channel_id,
        cover: { type, images },
        content,
      } = detail
      // 将数据回显到 Form 表单中
      // form.setFieldsValue(detail)
      form.setFieldsValue({
        title,
        channel_id,
        type,
        content,
      })

      // 回显图片数据
      const newFileList = images.map((item) => ({ url: item }))
      setFileList(newFileList)
      // 设置最大上传数量
      setMaxCount(type)
      // 将图片数据存储到 ref
      fileListRef.current = newFileList
    }
    loadData()
  }, [dispatch, id, isEdit, form])

  //监听上传文件改变时的事件
  const onUploadChange = (info) => {
    const newFileList = info.fileList.map((file) => {
      if (file.response) {
        //  有响应数据的时候
        return {
          url: file.response.data.url,
        }
      }
      // 如果还没有 r esponse 说明，图片还在上传过程中
      // 此时，为了让后续图片上传完成后，能够正确拿到图片地址，所以此处暂时将 file 返回
      // 如果不返回 file onChange 不会重复执行，这样将来无法拿到图片上传成功时的状态
      return file
    })
    // 将已上传的图片存储到 Ref 中
    fileListRef.current = newFileList

    setFileList(info.fileList)
  }

  // 修改图片上传数量
  const changeType = (e) => {
    const count = e.target.value
    setMaxCount(e.target.value)

    if (count === 1) {
      // 从 ref 中取出第一张
      // 判断 ref 中有没有图片，如果索引为 0 的没有，说明一张图片都没有
      // 此时，单图，直接设置为 空数组即可
      // 如果有，就拿到 索引为0 的图片然后组装陈数组，再给fileList（因为fileList是数组）
      const newFileList = fileListRef.current[0] ? [fileListRef.current[0]] : []
      setFileList(newFileList)
    } else if (count === 3) {
      // 从 ref 中取出全部
      setFileList(fileListRef.current)
    }
  }

  // 封装发布或编辑文章
  const saveArticle = async (values, msg, isDraft) => {
    // 判断图片删除数量和图片类型匹配不，不匹配直接拒绝
    if (values.type !== fileList.length) {
      return message.warning('封面数量也所选类型不匹配')
    }
    const { type, ...restValues } = values
    // 组装接口需要的数据
    const data = {
      ...restValues,
      cover: {
        type,
        images: fileList.map((item) => item.url),
      },
    }
    if (isEdit) {
      data.id = id
      msg = '编辑成功'
    }
    try {
      await dispatch(updateArticle(data, isDraft, isEdit))

      // 成功后跳转到内容管理页面
      message.success(msg, 1, () => {
        histroy.push('/home/article')
      })
    } catch {}
  }

  // 表单提交 - 发布文章 或 编辑文章
  const onFinish = async (values) => {
    try {
      saveArticle(values, '发表成功', false)
    } catch {}
  }

  // 存入草稿 - 发布文章时
  const saveDraft = async () => {
    try {
      const values = await form.validateFields()
      saveArticle(values, '存入草稿成功', true)
    } catch {}
  }

  return (
    <div className={styles.root}>
      <Card
        title={
          <Breadcrumb separator=">">
            <Breadcrumb.Item>
              <Link to="/home">首页</Link>
            </Breadcrumb.Item>
            <Breadcrumb.Item>
              {isEdit ? '编辑文章' : '发布文章'}
            </Breadcrumb.Item>
          </Breadcrumb>
        }
      >
        <Form
          labelCol={{ span: 4 }}
          wrapperCol={{ span: 16 }}
          initialValues={{ type: 1, content: '' }}
          onFinish={onFinish}
          // 将创建好的 form 设置为 Form 组件的 form 属性
          // 设置后，就可以通过 form 来拿到 Form 表单实例了
          form={form}
        >
          <Form.Item
            label="标题"
            name="title"
            rules={[{ required: true, message: '请输入文章标题' }]}
          >
            <Input placeholder="请输入文章标题" style={{ width: 400 }} />
          </Form.Item>
          <Form.Item
            label="频道"
            name="channel_id"
            rules={[{ required: true, message: '请选择文章频道' }]}
          >
            <Channel width={400} />
            {/* <Select placeholder="请选择文章频道" style={{ width: 400 }}>
              <Option value={0}>推荐</Option>
            </Select> */}
          </Form.Item>

          <Form.Item label="封面">
            <Form.Item name="type">
              <Radio.Group onChange={changeType}>
                <Radio value={1}>单图</Radio>
                <Radio value={3}>三图</Radio>
                <Radio value={0}>无图</Radio>
                {/* <Radio value={-1}>自动</Radio> */}
              </Radio.Group>
            </Form.Item>
            {maxCount !== 0 && (
              <Upload
                name="image"
                listType="picture-card"
                className="avatar-uploader"
                showUploadList
                action="http://geek.itheima.net/v1_0/upload"
                multiple={maxCount === 3}
                maxCount={maxCount}
                fileList={fileList}
                onChange={onUploadChange}
              >
                <div style={{ marginTop: 8 }}>
                  <PlusOutlined />
                </div>
              </Upload>
            )}
          </Form.Item>

          <Form.Item
            label="内容"
            name="content"
            rules={[{ required: true, message: '请输入文章内容' }]}
          >
            <ReactQuill
              className="publish-quill"
              theme="snow"
              placeholder="请输入文章内容"
            />
          </Form.Item>

          <Form.Item wrapperCol={{ offset: 4 }}>
            <Space>
              <Button size="large" type="primary" htmlType="submit">
                {isEdit ? '编辑文章' : '发布文章'}
              </Button>
              <Button size="large" onClick={saveDraft}>
                存入草稿
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </Card>
    </div>
  )
}

export default Publish
